#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "CRC/crc16.h"
#include "CRC/crc8.h"

int main() {
    printf("CRC Function Test Demo\n");
    printf("======================\n");
    
    // Test case 1: Simple sequence
    uint8_t test1[] = {0x01, 0x02, 0x03, 0x04, 0x05};
    printf("\nTest Case 1: Simple sequence\n");
    printf("Data: ");
    for (int i = 0; i < 5; i++) {
        printf("0x%02X ", test1[i]);
    }
    printf("\n");
    
    uint16_t crc1 = CRC_Compute(test1, 5);
    uint8_t sum1 = CheckSum(test1, 5);
    printf("CRC16: 0x%04X\n", crc1);
    printf("Checksum: 0x%02X\n", sum1);
    
    // Test case 2: String
    uint8_t test2[] = "Hello";
    printf("\nTest Case 2: String 'Hello'\n");
    printf("Data: ");
    for (int i = 0; i < 5; i++) {
        printf("0x%02X ", test2[i]);
    }
    printf("\n");
    
    uint16_t crc2 = CRC_Compute(test2, 5);
    uint8_t sum2 = CheckSum(test2, 5);
    printf("CRC16: 0x%04X\n", crc2);
    printf("Checksum: 0x%02X\n", sum2);
    
    // Test case 3: All zeros
    uint8_t test3[] = {0x00, 0x00, 0x00, 0x00};
    printf("\nTest Case 3: All zeros\n");
    printf("Data: ");
    for (int i = 0; i < 4; i++) {
        printf("0x%02X ", test3[i]);
    }
    printf("\n");
    
    uint16_t crc3 = CRC_Compute(test3, 4);
    uint8_t sum3 = CheckSum(test3, 4);
    printf("CRC16: 0x%04X\n", crc3);
    printf("Checksum: 0x%02X\n", sum3);
    
    // Test case 4: All ones
    uint8_t test4[] = {0xFF, 0xFF, 0xFF, 0xFF};
    printf("\nTest Case 4: All ones\n");
    printf("Data: ");
    for (int i = 0; i < 4; i++) {
        printf("0x%02X ", test4[i]);
    }
    printf("\n");
    
    uint16_t crc4 = CRC_Compute(test4, 4);
    uint8_t sum4 = CheckSum(test4, 4);
    printf("CRC16: 0x%04X\n", crc4);
    printf("Checksum: 0x%02X\n", sum4);
    
    // Test case 5: Command sequence
    uint8_t cmd[] = {0x5B, 0x5B, 0x51, 0x30, 0x00, 0x00};
    printf("\nTest Case 5: Command sequence\n");
    printf("Data: ");
    for (int i = 0; i < 6; i++) {
        printf("0x%02X ", cmd[i]);
    }
    printf("\n");
    
    uint16_t crc5 = CRC_Compute(cmd, 6);
    uint8_t sum5 = CheckSum(cmd, 6);
    printf("CRC16: 0x%04X\n", crc5);
    printf("Checksum: 0x%02X\n", sum5);
    
    // Test case 6: CRC8-ATM for command datagram
    uint8_t datagram[] = {0x5B, 0x5B, 0x51, 0x30, 0x00, 0x00}; // last byte reserved for CRC
    printf("\nTest Case 6: CRC8-ATM for command\n");
    printf("Payload: ");
    for (int i = 0; i < 5; i++) {
        printf("0x%02X ", datagram[i]);
    }
    printf("\n");

    // Option A: compute and set last byte via helper
    CRC8_ATM_UpdateLastByte(datagram, 6);
    printf("CRC8-ATM: 0x%02X\n", datagram[5]);

    // Show final datagram with CRC appended
    printf("Final datagram: ");
    for (int i = 0; i < 6; i++) {
        printf("0x%02X ", datagram[i]);
    }
    printf("\n");

    // Option B: direct calculation over payload (first 5 bytes)
    uint8_t crc8 = CRC8_ATM_Calc(datagram, 5);
    printf("CRC8-ATM (recalc over payload): 0x%02X\n", crc8);
    
    printf("\nTest completed!\n");
    return 0;
}
